<template>
  <a-modal
    :visible="visible"
    :title="carryFromIsBill ? '新建转入' : '金额结转'"
    :maskClosable="false"
    @cancel="closeModal"
    @ok="handleSubmit"
    :confirmLoading="submitLoading"
    :width="1000"
    :okText="carryFromIsBill ? '保存&发起审批' : '保存'"
    :destroyOnClose="true"
  >
    <div class="carry-content">
      <section class="statistics">
        <a-row class="quantity" type="flex">
          <a-col class="text-center" >
            <div class="number-width">
              {{totalMax}}
              <span class="num-unit">元</span>
            </div>
            <div class="text">{{carryFromIsBill ? '账单可转入金额' : '待结转金额'}}</div>
          </a-col>
          <a-col class="text-center">
            <div class="number-width">
              {{surplusTotal}}
              <span class="num-unit">元</span>
            </div>
            <div class="text">{{carryFromIsBill ? '账单可转入剩余金额' : '待结转剩余金额'}}</div>
          </a-col>
        </a-row>
      </section>
      <a-card size="small" :title="`选择${carryFromIsBill ? '转入' : '结转'}来源`" class="mt-10">
        <template #extra>
          <a-space>
            <a-input-search
              v-if="source == 3"
              v-model:value="keywords"
              style="width: 280px"
              placeholder="搜索对方名称、房号、合同编号"
              @search="onSearch"
            />
            <a-select
              style="width: 140px"
              v-model:value="source"
              :options="sourceList"
              @change="changeSource"
            />
          </a-space>
        </template>
        <a-table
          :dataSource="dataList"
          :loading="tableLoading"
          :rowSelection="rowSelection"
          :pagination="pagination"
          :columns="defaultColumns"
          :scroll="{ y: 500}"
          rowKey="id"
          @change="handleTableChange"
        ></a-table>
      </a-card>

      <a-card size="small" :title="`填写${carryFromIsBill ? '转入' : '结转'}金额`" class="mt-10">
        <template #extra>
          <a-space>
            <a-button @click.stop="clearAmount">清空金额</a-button>
          </a-space>
        </template>
        <a-table
          :dataSource="selectRows"
          :pagination="false"
          :columns="carryColumns"
          :scroll="{ y: 500}"
          rowKey="id"
        >
          <template #bodyCell="{ text, record, index, column }">
            <template v-if="column.key === 'amount'">
              <a-input-number
                v-model:value="record.amount"
                :min="0"
                :precision="2"
                :max="getMaxAmount(selectRows, record)"
                style="width: 100%"
              />
            </template>
            <template v-if="column.key === 'action'">
              <a-popconfirm title="是否确定要删除?" @confirm="handleRemove(record)">
                <a-button type="link" danger
                >删除</a-button
                >
              </a-popconfirm>
            </template>
          </template>
        </a-table>
      </a-card>

      <!--   附件   -->
      <a-col v-if="carryFromIsBill" size="small" class="mt-10">
        <attachment-info
            :params="attachParams"
            :addfolder="false"
            :batchupload="false"
            :object="false"
            @getObjectId="getObjectId"
        />
      </a-col>
    </div>
  </a-modal>
</template>

<script>
import { defineComponent, reactive, toRefs, computed, watch, ref } from "vue";
import {Form, message, TreeSelect} from "ant-design-vue";
import request from "@/common/utils/request";
import _ from "lodash";
import BLCOMMON from "bl-common-vue3";
import utils from "@/common/utils/utils";
import AttachmentInfo from "@/components/contract/AttachmentInfo/index.vue";

export default defineComponent({
  name: "AmountCarryOver",
  components: {AttachmentInfo},
  props: {
    // 打开弹框
    visible: {
      type: Boolean,
      default: false,
    },
    // 转入 账单金额总和 （用于减去）
    billList: {
      type: Array,
      default: () => [], // 本次操作全部为入的账单的结转列表（用于可结转金额的抵消） // 可以用map
    },
    currentBill: {
      type: Object,
      default: () => {}, // 本次操作账单的结转列表 children
    },
    contractId: {
      type: [Number, String],
      default: "",
    },
    carryFrom: {
      type: String,
      default: "contract", // 合同结转 账单结转
    }
  },

  setup(props, { emit }) {
    const state = reactive({
      source: '1',
      keywords: '',
      page: 1,
      limit: 10,
      total: 0,
      tableLoading: false,
      dataList: [],
      selectRows: [],
      totalMax: 0,
      intoBillMap: {}, // 映射 非本次的账单 已经 结转的数据
      submitLoading: false,
      attachParams: {
        type: 1,
      },
      object_id:'',
    });

    const getObjectId = (id) => {
      state.object_id = id;
    };

    const pagination = computed(() => ({
      total: state.total,
      current: state.page,
      pageSize: state.limit,
      showSizeChanger: true,
    }));

    const closeModal = () => {
      emit("handleClose");
    };

    const surplusTotal = computed(() => {
      let total = state.selectRows.reduce((acc, cur) => utils.countSum([acc, Number(cur.amount)]), 0);
      return utils.countSum([state.totalMax, -Number(total)]);
    });

    const carryFromIsBill = computed(() => {
      return props.carryFrom == 'bill';
    });

    const sourceList = computed(() => {
      let list = _.cloneDeep(SOURCE_LIST);
      if (carryFromIsBill.value) {
        [list[0], list[1]] = [list[1], list[0]]
      }
      return list;
    });

    const handleSubmit = () => {
      if (surplusTotal.value < 0) {
        message.warn(`本次${carryFromIsBill.value ? '转出' : '结转'}金额总和不能大于${carryFromIsBill.value ? '账单可转入金额' : '待结转金额'},请修改后再进行保存`)
        return
      }
      let rows = _.cloneDeep(state.selectRows).filter((v) => v.amount > 0);
      if (carryFromIsBill.value) {
        // 账单结转
        if (rows?.length) {
          state.submitLoading = true;
          let params = {
            status: 1,
            needMsg: true,
          };
          let from_bill_info = rows.map((item) => {
            return {
              from_bill_id: item.bill_id,
              amount: item.amount,
            }
          });
          params.data = [
            {
              origin_bill_id: props.currentBill?.id,
              from_bill_info,
            }
          ]
          params.object_id = state.object_id

          request
            .post("/org", "/billTransfer/addTransfer", params)
            .then((res) => {
              message.success(res.msg || "保存成功");
              state.submitLoading = false;
              emit("handleSuccess");
            }).catch(() => {
            state.submitLoading = false;
          });
        } else {
          message.warning('本次转出金额总和为0，修改后再进行保存操作哦~')
        }
      } else {
        // 合同结转
        emit("handleSubmit", rows, props.currentBill?.id);
      }
    };

    const onSearch = () => {

    };

    const selectedRowKeys = computed(() => {
      return state.selectRows.map((item) => item.id)
    });

    const rowSelection = computed(() => ({
      selectedRowKeys: selectedRowKeys.value,
      onSelect: onSelect,
      onSelectAll: onSelectAll,
    }));

    const onSelect = (record, selected) => {
      record.amount = 0;
      if (selected) {
        let _record = _.cloneDeep(record);
        let rows = _.cloneDeep(state.selectRows);
        rows.push(_record);
        _record.amount = getMaxAmount(rows, _record);
        state.selectRows.push(_record);
      } else {
        state.selectRows = state.selectRows.filter((item) => item.id !== record.id);
      }
    };

    const onSelectAll = (selected, selectedRows, changeRows) => {
      changeRows.forEach((item) => {
        item.amount = 0;
        if (selected) {
          if (state.selectRows.findIndex((v) => v.id === item.id) == -1) {
            onSelect(item, selected)
          }
        } else {
          state.selectRows = state.selectRows.filter((v) => v.id !== item.id);
        }
      })
    };

    const handleRemove = (record) => {
      onSelect(record, false);
    };

    const getActualAmount = (originAmount, amountList) => {
      // 原始金额 减去 其余账单结转金额
      let total = amountList.reduce((acc, cur) => utils.countSum([acc, Number(cur.amount)]), 0);
      return utils.countSum([Number(originAmount), -Number(total)]);
    };

    const getBillList = (init = false) => {
      state.tableLoading = true;
      if (init) {
        state.page = 1;
      }
      let params = {
        page: state.page,
        pageSize: state.limit,
        type: state.source,
        contract_id: props.contractId,
      };
      if (carryFromIsBill.value) {
        delete params.contract_id;
        params.bill_id = props.currentBill?.id;
      }
      if (state.source == 3) {
        params.keywords = state.keywords;
      }
      request
        .get("/org", "/billTransfer/transferSourceList", params)
        .then((res) => {
          let data = res?.list?.data || [];
          data = data.map((item) => {
            item.id = `carry_${item.bill_id}`;
            item.isInto = true;
            item.actual_retreat_now = item.actual_retreat;
            if (state.intoBillMap[item.bill_id]) {
              // 有结转 // 累加 // 计算初始金额
              item.actual_retreat_now = getActualAmount(item.actual_retreat, state.intoBillMap[item.bill_id]);
            }
            return item
          })
          state.dataList = data;
          state.total = res?.list?.total || 0;
        })
        .finally(() => {
          state.tableLoading = false;
        });
    };

    const handleTableChange = (pager, filters, sorter) => {
      state.page = pager.current;
      state.limit = pager.pageSize;
      getBillList();
    };

    const changeSource = () => {
      getBillList(true);
    };

    const getIntoBillMap = async () => {
      if (props.billList?.length) {
        const childrenData = props.billList.filter(item => item.children && item.children.length > 0 && item.is_fu != 1 && item.id !== props.currentBill.id).map(item => item.children).flat();
        const billsMap = childrenData.reduce((acc, item) => {
          if (acc[item.bill_id]) {
            acc[item.bill_id].push(_.cloneDeep(item));
          } else {
            acc[item.bill_id] = [_.cloneDeep(item)];
          }
          return acc;
        }, {});
        state.intoBillMap = billsMap;
      }
    };

    // 清空金额
    const clearAmount = () => {
      state.selectRows.forEach((item) => {
        item.amount = 0;
      });
    };

    const init = async () => {
      if (carryFromIsBill.value) {
        state.source = '2';
      }
      state.totalMax = Number(props.currentBill?.actual_retreat);
      await getIntoBillMap();
      getBillList(true);
      state.selectRows = _.cloneDeep(props.currentBill?.children || []).map((v) => {
        if (state.intoBillMap[v.bill_id]) {
          // 有结转 // 累加 // 计算初始金额
          v.actual_retreat_now = getActualAmount(v.actual_retreat, state.intoBillMap[v.bill_id]);
        } else {
          v.actual_retreat_now = v.actual_retreat;
        }
        return v;
      });
    };

    const reset = () => {
      state.source = '1';
      state.keywords = '';
      state.limit = 10;
      state.total = 0;
      state.tableLoading = false;
      state.dataList = [];
      state.selectRows = [];
      state.totalMax = 0;
      state.intoBillMap = {};
      state.submitLoading = false;
    };

    const getMaxAmount = (rows, record) => {
      let canInto = Number(record.actual_retreat_now);
      let otherBill = rows.filter((v) => v.id !== record.id);
      let otherBillAmountTotal = otherBill.reduce((acc, cur) => utils.countSum([acc, Number(cur.amount)]), 0);
      let surplusTotal =  utils.countSum([state.totalMax, -otherBillAmountTotal]);
      return surplusTotal > canInto ? canInto : surplusTotal;
    };

    watch(
      () => props.visible,
      (visible) => {
        if (visible) {
          init();
        } else {
          reset();
        }
      }
    );

    const defaultColumns = computed(() => {
      return  [
        {
          title: BLCOMMON.utils.L("租客") + "名称",
          dataIndex: "owner_name",
          key: "owner_name",
        },
        {
          title: "项目名称",
          dataIndex: "village_name",
          key: "village_name",
        },
        {
          title: "楼层-房号",
          key: "roomInfo",
          dataIndex: "roomInfo",
        },
        {
          title: "费用类型",
          dataIndex: "cost_type_txt",
          key: "cost_type_txt",
        },
        {
          title: carryFromIsBill.value ? "账单周期" : "区间",
          dataIndex: "contractOn",
          key: "contractOn",
          width: 200,
        },
        {
          title: carryFromIsBill.value ? "可转出金额" : "可结转金额",
          dataIndex: "actual_retreat_now",
          key: "actual_retreat_now",
          width: 110,
        },
      ]
    });

    const carryColumns = computed(() => {
      return _.cloneDeep(defaultColumns.value).concat(
        [
          {
            title: carryFromIsBill.value ? "本次转出金额" : "本次结转金额",
            dataIndex: "amount",
            key: "amount",
            width: 140,
          },
          {
            title: "操作",
            dataIndex: "id",
            key: "action",
          },
        ]
      )
    })

    return {
      ...toRefs(state),
      sourceList,
      rowSelection,
      pagination,
      surplusTotal,
      carryFromIsBill,
      defaultColumns,
      carryColumns,
      closeModal,
      handleSubmit,
      onSearch,
      handleTableChange,
      changeSource,
      handleRemove,
      clearAmount,
      getMaxAmount,
      getObjectId,
    };
  },
});

const SOURCE_LIST = [
  {
    label: "本合同账单",
    value: "1",
  },
  {
    label: "本租客账单",
    value: "2",
  },
  {
    label: "外部账单",
    value: "3",
  },
];

</script>

<style lang="less" scoped>
.carry-content {
  max-height: calc(80vh - 100px);
  overflow-y: auto;
}
.statistics {
  .quantity {
    width: 100%;
    background-color: #f2f2f2;
    height: 80px;
    align-items: center;
    padding: 10px;
    .text-center {
      text-align: center;
      position: relative;
      flex: 1;
      width: 0;
      .text {
        color: #8d8d8d;
      }
      .number-width {
        color: @primary-color;
        font-weight: 700;
        font-size: 26px;
        width: 100%;
        // 文字不折行
        overflow: hidden;
        word-break: break-all;
        white-space: nowrap;
        text-overflow: ellipsis;
      }
      .num-unit {
        font-size: 12px;
        font-weight: initial;
      }
    }
  }
  .text-center:not(:last-child):after {
    content: "";
    position: absolute;
    right: 0;
    top: 25%;
    height: 50%;
    border-left: 1px solid #d2d2d2;
  }
}
</style>
